<template>
  <div class="process-panel__container" :style="{ width: `${this.width}px` }">
    <el-collapse v-model="activeTab">
      <el-collapse-item name="base">
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-info"></i>常规
        </div>
        <element-base-info
          :id-edit-disabled="idEditDisabled"
          :business-object="elementBusinessObject"
          :type="elementType"
          :appId="appId"
          :getTitleField="getTitleField"
          :setTableName="setTableName"
          ref="baseInfo"
        />
      </el-collapse-item>
      <el-collapse-item
        name="condition"
        v-if="elementType === 'Process'"
        key="message"
      >
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-s-comment"></i>消息与信号
        </div>
        <signal-and-massage />
      </el-collapse-item>
      <el-collapse-item
        name="condition"
        v-if="conditionFormVisible"
        key="condition"
      >
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-s-promotion"></i>流转条件
        </div>
        <flow-condition
          :business-object="elementBusinessObject"
          :type="elementType"
          :getFormlist="getFormlist"
          :id="elementId"
        />
      </el-collapse-item>
      <el-collapse-item
        name="condition"
        v-if="formVisible || elementType.indexOf('Task') !== -1"
        key="form"
      >
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-s-order"></i>表单
        </div>
        <element-form
          :id="elementId"
          :type="elementType"
          :appId="appId"
          ref="formRef"
          :feildList="feildList"
          :setFileList="setFileList"
          :getFeildList="getFeildList"
          :setNodeList="setNodeList"
          :nodeListObj="nodeListObj"
          :titleField="titleField"
          :setTableName="setTableName"
        />
      </el-collapse-item>
      <el-collapse-item
        name="task"
        v-if="elementType.indexOf('Task') !== -1"
        key="task"
      >
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-s-claim"></i>任务
        </div>
        <element-task
          :id="elementId"
          :type="elementType"
          :refreshAttributes="refreshAttributes"
        />
      </el-collapse-item>
      <el-collapse-item
        name="multiInstance"
        v-if="elementType.indexOf('Task') !== -1 && elementType !== 'UserTask'"
        key="multiInstance"
      >
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-s-help"></i>多实例
        </div>
        <element-multi-instance
          :business-object="elementBusinessObject"
          :type="elementType"
        />
      </el-collapse-item>
      <el-collapse-item name="listeners" key="listeners">
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-message-solid"></i>执行监听器
        </div>
        <element-listeners :id="elementId" :type="elementType" />
      </el-collapse-item>
      <el-collapse-item
        name="taskListeners"
        v-if="elementType === 'UserTask'"
        key="taskListeners"
      >
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-message-solid"></i>任务监听器
        </div>
        <user-task-listeners :id="elementId" :type="elementType" />
      </el-collapse-item>
      <el-collapse-item name="extensions" key="extensions">
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-circle-plus"></i>扩展属性
        </div>
        <element-properties
          :id="elementId"
          :type="elementType"
          ref="properties"
        />
      </el-collapse-item>
      <el-collapse-item name="other" key="other" v-if="formVisible">
        <div slot="title" class="panel-tab__title">
          <i class="el-icon-s-promotion"></i>其他
        </div>
        <element-other-config
          :id="elementId"
          :type="elementType"
          :getInterfaceList="getInterfaceList"
          :setInterfaceList="setInterfaceList"
        />
      </el-collapse-item>
    </el-collapse>
  </div>
</template>
<script>
import ElementBaseInfo from "./base/ElementBaseInfo";
import ElementOtherConfig from "./other/ElementOtherConfig";
import ElementTask from "./task/ElementTask";
import ElementMultiInstance from "./multi-instance/ElementMultiInstance";
import FlowCondition from "./flow-condition/FlowCondition";
import SignalAndMassage from "./signal-message/SignalAndMessage";
import ElementListeners from "./listeners/ElementListeners";
import ElementProperties from "./properties/ElementProperties";
import ElementForm from "./form/ElementForm";
import UserTaskListeners from "./listeners/UserTaskListeners";
import { getField } from "@/api/app/dataModel/entityModel";
import { getAppProcessTitleConfig } from "@/api/workflow/model";

/**
 * 侧边栏
 * @Author MiyueFE
 * @Home https://github.com/miyuesc
 * @Date 2021年3月31日18:57:51 真心很贵你别逢人就给 感情很重你别轻易卑微 会有人来也就会有人走 往南的人总会陪你向北
 */
export default {
  name: "BpmnPropertiesPanel",
  components: {
    UserTaskListeners,
    ElementForm,
    ElementProperties,
    ElementListeners,
    SignalAndMassage,
    FlowCondition,
    ElementMultiInstance,
    ElementTask,
    ElementOtherConfig,
    ElementBaseInfo,
  },
  componentName: "BpmnPropertiesPanel",
  props: {
    bpmnModeler: Object,
    prefix: {
      type: String,
      default: "camunda",
    },
    width: {
      type: Number,
      default: 480,
    },
    idEditDisabled: {
      type: Boolean,
      default: true,
    },
    appId: {
      type: String,
      default: "",
    },
  },
  provide() {
    return {
      prefix: this.prefix,
      width: this.width,
    };
  },
  data() {
    return {
      activeTab: "base",
      elementId: "",
      elementType: "",
      elementBusinessObject: {}, // 元素 businessObject 镜像，提供给需要做判断的组件使用
      conditionFormVisible: false, // 流转条件设置
      formVisible: false, // 表单配置
      feildList: {},
      nodeListObj: {},
      interfaceList: {},
      titleField: undefined,
      titleName: [],
      resetAttributesList: undefined,
    };
  },
  watch: {
    elementId: {
      handler() {
        this.activeTab = "base";
      },
    },
  },
  created() {
    this.initModels();
  },
  methods: {
    async getFormlist (){
      const data = await this.$refs.baseInfo?.initFormFields();
      return data 
    },
    refreshAttributes() {
      this.$refs.properties.resetAttributesList();
    },
    async getFeildList(id) {
      if(!id) return 
      const res = await getField({ id });
      const arr = [];
      res.data?.formFields?.forEach((item) => {
        const { label, field } = item;
        arr.push({
          columnLabel: label,
          columnField: field,
          disabled: false,
          view: true,
          taskId: this.$refs.formRef?.id,
          appFormId: this.$refs.formRef?.formKey.slice(4),
        });
      });
      this.$set(this.feildList, this.$refs.formRef?.id, arr);
    },
    async getformRefFieldList() {
      return this.feildList || {};
    },
    async getformRefNode() {
      return this.nodeListObj || {};
    },
    async getInterfaceList() {
      return this.interfaceList || {};
    },
    setFileList(val, data) {
      this.$set(this.feildList, val, data);
    },
    setNodeList(val, data) {
      this.$set(this.nodeListObj, val, data);
    },
    setInterfaceList(val, data) {
      this.$set(this.interfaceList, val, data);
    },
    async setTitleField() {
      const data = this.$refs.baseInfo;
      const titleField = data?.titleField;
      return titleField;
    },
    setTableName(val) {
      this.tableName = val;
    },
    async getTitleField(id) {
      const res = await getAppProcessTitleConfig({
        processKey: id,
      });
      if (res.rows?.length && res.rows[0]?.titleField) {
        let titleField = JSON.parse(res.rows[0]?.titleField);
        let titleFieldValue = [];
        let titleFieldLabel = "";
        titleField.forEach((item, index) => {
          titleFieldValue.push(item.options.name);
          if (index + 1 !== titleField.length) {
            titleFieldLabel += `${item.options.label}-`;
          } else {
            titleFieldLabel += item.options.label;
          }
        });
        return {
          titleField,
          titleFieldValue,
          titleFieldLabel,
        };
      }
      return {
        titleField: [],
        titleFieldValue: [],
        titleFieldLabel: "",
      };
    },
    initModels() {
      // 初始化 modeler 以及其他 moddle
      if (!this.bpmnModeler) {
        // 避免加载时 流程图 并未加载完成
        this.timer = setTimeout(() => this.initModels(), 10);
        return;
      }
      if (this.timer) clearTimeout(this.timer);
      window.bpmnInstances = {
        modeler: this.bpmnModeler,
        modeling: this.bpmnModeler.get("modeling"),
        moddle: this.bpmnModeler.get("moddle"),
        eventBus: this.bpmnModeler.get("eventBus"),
        bpmnFactory: this.bpmnModeler.get("bpmnFactory"),
        elementFactory: this.bpmnModeler.get("elementFactory"),
        elementRegistry: this.bpmnModeler.get("elementRegistry"),
        replace: this.bpmnModeler.get("replace"),
        selection: this.bpmnModeler.get("selection"),
      };
      this.getActiveElement();
    },
    getActiveElement() {
      // 初始第一个选中元素 bpmn:Process
      this.initFormOnChanged(null);
      this.bpmnModeler.on("import.done", (e) => {
        this.initFormOnChanged(null);
      });
      // 监听选择事件，修改当前激活的元素以及表单
      this.bpmnModeler.on("selection.changed", ({ newSelection }) => {
        this.initFormOnChanged(newSelection[0] || null);
      });
      this.bpmnModeler.on("element.changed", ({ element }) => {
        // 保证 修改 "默认流转路径" 类似需要修改多个元素的事件发生的时候，更新表单的元素与原选中元素不一致。
        if (element && element.id === this.elementId) {
          this.initFormOnChanged(element);
        }
      });
    },
    // 初始化数据
    initFormOnChanged(element) {
      let activatedElement = element;
      if (!activatedElement) {
        activatedElement =
          window.bpmnInstances.elementRegistry.find(
            (el) => el.type === "bpmn:Process"
          ) ??
          window.bpmnInstances.elementRegistry.find(
            (el) => el.type === "bpmn:Collaboration"
          );
      }
      if (!activatedElement) return;
      // console.log(`
      //         ----------
      // select element changed:
      //           id:  ${activatedElement.id}
      //         type:  ${activatedElement.businessObject.$type}
      //         ----------
      //         `);
      // console.log("businessObject: ", activatedElement.businessObject);
      window.bpmnInstances.bpmnElement = activatedElement;
      this.bpmnElement = activatedElement;
      this.elementId = activatedElement.id;
      this.elementType = activatedElement.type.split(":")[1] || "";
      this.elementBusinessObject = JSON.parse(
        JSON.stringify(activatedElement.businessObject)
      );
      this.conditionFormVisible = !!(
        this.elementType === "SequenceFlow" &&
        activatedElement.source &&
        activatedElement.source.type.indexOf("StartEvent") === -1
      );
      this.formVisible =
        this.elementType === "UserTask" || this.elementType === "StartEvent";
    },
    beforeDestroy() {
      window.bpmnInstances = null;
    },
  },
};
</script>
